The patch extends the VMCS handling to support both 32-bit and 64-bit
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Mon, 4 Jul 2005 08:20:20 +0000 (08:20 +0000)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Mon, 4 Jul 2005 08:20:20 +0000 (08:20 +0000)
guests. Please apply. It also includes cleanups.

Signed-off-by: Jun Nakajima <jun.nakajima@intel.com>
Signed-off-by: Chengyuan Li <chengyuan.li@intel.com>
Signed-off-by: Yunhong Jiang <yunhong.jiang@intel.com>
xen/arch/x86/vmx_platform.c
xen/arch/x86/vmx_vmcs.c
xen/include/asm-x86/vmx_intercept.h

index c2f7cd740fd4c5c8172d03ba0c79c968fbd37a96..bcf80e3d684e8f9822feb4c0984ae42eae4ced33 100644 (file)
@@ -503,7 +503,7 @@ static int vmx_decode(const unsigned char *inst, struct instruction *thread_inst
 
 int inst_copy_from_guest(unsigned char *buf, unsigned long guest_eip, int inst_len)
 {
-    l1_pgentry_t gpte;
+    unsigned long gpa;
     unsigned long mfn;
     unsigned char *inst_start;
     int remaining = 0;
@@ -513,8 +513,9 @@ int inst_copy_from_guest(unsigned char *buf, unsigned long guest_eip, int inst_l
 
     if ( vmx_paging_enabled(current) )
     {
-        gpte = gva_to_gpte(guest_eip);
-        mfn = phys_to_machine_mapping(l1e_get_pfn(gpte));
+        gpa = gva_to_gpa(guest_eip);
+        mfn = phys_to_machine_mapping(gpa >> PAGE_SHIFT);
+
         /* Does this cross a page boundary ? */
         if ( (guest_eip & PAGE_MASK) != ((guest_eip + inst_len) & PAGE_MASK) )
         {
@@ -533,8 +534,9 @@ int inst_copy_from_guest(unsigned char *buf, unsigned long guest_eip, int inst_l
 
     if ( remaining )
     {
-        gpte = gva_to_gpte(guest_eip+inst_len+remaining);
-        mfn = phys_to_machine_mapping(l1e_get_pfn(gpte));
+        gpa = gva_to_gpa(guest_eip+inst_len+remaining);
+        mfn = phys_to_machine_mapping(gpa >> PAGE_SHIFT);
+
         inst_start = map_domain_page(mfn);
         memcpy((char *)buf+inst_len, inst_start, remaining);
         unmap_domain_page(inst_start);
index fc2376ba76774dbd3b407746205b647fcd27ae1a..3ec448f894294ed9f728eec647a71021f65dab9b 100644 (file)
@@ -65,8 +65,12 @@ static inline int construct_vmcs_controls(void)
 
     error |= __vmwrite(CPU_BASED_VM_EXEC_CONTROL, 
                        MONITOR_CPU_BASED_EXEC_CONTROLS);
-
+#if defined (__x86_64__)
+    error |= __vmwrite(VM_EXIT_CONTROLS, 
+      MONITOR_VM_EXIT_CONTROLS | VM_EXIT_CONTROLS_IA_32E_MODE);
+#else
     error |= __vmwrite(VM_EXIT_CONTROLS, MONITOR_VM_EXIT_CONTROLS);
+#endif
     error |= __vmwrite(VM_ENTRY_CONTROLS, MONITOR_VM_ENTRY_CONTROLS);
 
     return error;
@@ -93,6 +97,11 @@ struct host_execution_env {
     unsigned long tr_base;
     unsigned long ds_base;
     unsigned long cs_base;
+#ifdef __x86_64__ 
+    unsigned long fs_base; 
+    unsigned long gs_base; 
+#endif 
+
     /* control registers */
     unsigned long cr3;
     unsigned long cr0;
@@ -230,8 +239,8 @@ construct_init_vmcs_guest(struct cpu_user_regs *regs,
     /* interrupt */
     error |= __vmwrite(VM_ENTRY_INTR_INFO_FIELD, 0);
     /* mask */
-    error |= __vmwrite(CR0_GUEST_HOST_MASK, 0xffffffff);
-    error |= __vmwrite(CR4_GUEST_HOST_MASK, 0xffffffff);
+    error |= __vmwrite(CR0_GUEST_HOST_MASK, -1UL);
+    error |= __vmwrite(CR4_GUEST_HOST_MASK, -1UL);
 
     error |= __vmwrite(PAGE_FAULT_ERROR_CODE_MASK, 0);
     error |= __vmwrite(PAGE_FAULT_ERROR_CODE_MATCH, 0);
@@ -298,9 +307,19 @@ construct_init_vmcs_guest(struct cpu_user_regs *regs,
     shadow_cr &= ~X86_CR0_PG;
     error |= __vmwrite(CR0_READ_SHADOW, shadow_cr);
     /* CR3 is set in vmx_final_setup_guest */
+#ifdef __x86_64__
+    error |= __vmwrite(GUEST_CR4, host_env->cr4 & ~X86_CR4_PAE);
+    printk("construct_init_vmcs_guest: guest CR4 is %lx\n", host_env->cr4 );
+#else
     error |= __vmwrite(GUEST_CR4, host_env->cr4);
+#endif
     shadow_cr = host_env->cr4;
+
+#ifdef __x86_64__
+    shadow_cr &= ~(X86_CR4_PGE | X86_CR4_VMXE | X86_CR4_PAE);
+#else
     shadow_cr &= ~(X86_CR4_PGE | X86_CR4_VMXE);
+#endif
     error |= __vmwrite(CR4_READ_SHADOW, shadow_cr);
 
     error |= __vmwrite(GUEST_ES_BASE, host_env->ds_base);
@@ -339,16 +358,24 @@ static inline int construct_vmcs_host(struct host_execution_env *host_env)
     error |= __vmwrite(HOST_ES_SELECTOR, host_env->ds_selector);
     error |= __vmwrite(HOST_SS_SELECTOR, host_env->ds_selector);
     error |= __vmwrite(HOST_DS_SELECTOR, host_env->ds_selector);
+#if defined (__i386__)
     error |= __vmwrite(HOST_FS_SELECTOR, host_env->ds_selector);
     error |= __vmwrite(HOST_GS_SELECTOR, host_env->ds_selector);
+    error |= __vmwrite(HOST_FS_BASE, host_env->ds_base); 
+    error |= __vmwrite(HOST_GS_BASE, host_env->ds_base); 
 
+#else
+    rdmsrl(MSR_FS_BASE, host_env->fs_base); 
+    rdmsrl(MSR_GS_BASE, host_env->gs_base); 
+    error |= __vmwrite(HOST_FS_BASE, host_env->fs_base); 
+    error |= __vmwrite(HOST_GS_BASE, host_env->gs_base); 
+
+#endif
     host_env->cs_selector = __HYPERVISOR_CS;
     error |= __vmwrite(HOST_CS_SELECTOR, host_env->cs_selector);
 
     host_env->ds_base = 0;
     host_env->cs_base = 0;
-    error |= __vmwrite(HOST_FS_BASE, host_env->ds_base);
-    error |= __vmwrite(HOST_GS_BASE, host_env->ds_base);
 
 /* Debug */
     __asm__ __volatile__ ("sidt  (%0) \n" :: "a"(&desc) : "memory");
@@ -366,6 +393,12 @@ static inline int construct_vmcs_host(struct host_execution_env *host_env)
     host_env->cr4 = crn;
     error |= __vmwrite(HOST_CR4, crn);
     error |= __vmwrite(HOST_RIP, (unsigned long) vmx_asm_vmexit_handler);
+#ifdef __x86_64__ 
+    /* TBD: support cr8 for 64-bit guest */ 
+    __vmwrite(VIRTUAL_APIC_PAGE_ADDR, 0); 
+    __vmwrite(TPR_THRESHOLD, 0); 
+    __vmwrite(SECONDARY_VM_EXEC_CONTROL, 0); 
+#endif 
 
     return error;
 }
index ab54682b2a92e3fd98e0ead258ae85b60f771eda..9465a7147be62060c01a392693580151a0692e8f 100644 (file)
@@ -8,7 +8,7 @@
 #include <xen/errno.h>
 #include <public/io/ioreq.h>
 
-#define MAX_IO_HANDLER 6
+#define MAX_IO_HANDLER 10
 
 typedef int (*intercept_action_t)(ioreq_t*);